~ubuntu-branches/ubuntu/vivid/php-codesniffer/vivid

« back to all changes in this revision

Viewing changes to PHP_CodeSniffer-1.5.4/CodeSniffer/Standards/Squiz/Sniffs/Commenting/InlineCommentSniff.php

  • Committer: Package Import Robot
  • Author(s): David Prévot, Greg Sherwood, Alexey, Emily, David Prévot
  • Date: 2014-09-26 13:44:35 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140926134435-wvjq16miqq4d60y0
Tags: 1.5.5-1
[ Greg Sherwood ]
* Improved closure support in Generic ScopeIndentSniff
* Improved indented PHP tag support in Generic ScopeIndentSniff
* Standards can now be located within hidden directories
 (further fix for bug #20323)
* Fixed bug #20373 : Inline comment sniff tab handling way
* Fixed bug #20378 : Report appended to existing file if no errors
  found in run
* Fixed bug #20381 : Invalid "Comment closer must be on a new line"
* PHP tokenizer no longer converts class/function names to special
  tokens types
* Fixed bug #20386 : Squiz.Commenting.ClassComment.SpacingBefore
  thrown if first block comment
* Squiz and PEAR FunctionCommentSnif now support _()
* PEAR ValidFunctionNameSniff no longer throws an error for _()
* Fixed bug #248 : FunctionCommentSniff expects ampersand on param name
* Fixed bug #248 in Squiz sniff as well
* Fixed bug #265 : False positives with type hints in ForbiddenFunctionsSniff
* Prepare for 1.5.5 release

[ Alexey ]
* Allowed single undersored methods and functions

[ Emily ]
* Added var_dump to discouraged functions sniff

[ David Prévot ]
* Revert "Add XS-Testsuite still needed for ci.d.n"
* Add self to uploaders
* Bump standards version to 3.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * Squiz_Sniffs_Commenting_InlineCommentSniff.
4
 
 *
5
 
 * PHP version 5
6
 
 *
7
 
 * @category  PHP
8
 
 * @package   PHP_CodeSniffer
9
 
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 
 * @author    Marc McIntyre <mmcintyre@squiz.net>
11
 
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
 
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
 
 * @link      http://pear.php.net/package/PHP_CodeSniffer
14
 
 */
15
 
 
16
 
/**
17
 
 * Squiz_Sniffs_Commenting_InlineCommentSniff.
18
 
 *
19
 
 * Checks that there is adequate spacing between comments.
20
 
 *
21
 
 * @category  PHP
22
 
 * @package   PHP_CodeSniffer
23
 
 * @author    Greg Sherwood <gsherwood@squiz.net>
24
 
 * @author    Marc McIntyre <mmcintyre@squiz.net>
25
 
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
 
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
 
 * @version   Release: 1.5.4
28
 
 * @link      http://pear.php.net/package/PHP_CodeSniffer
29
 
 */
30
 
class Squiz_Sniffs_Commenting_InlineCommentSniff implements PHP_CodeSniffer_Sniff
31
 
{
32
 
 
33
 
    /**
34
 
     * A list of tokenizers this sniff supports.
35
 
     *
36
 
     * @var array
37
 
     */
38
 
    public $supportedTokenizers = array(
39
 
                                   'PHP',
40
 
                                   'JS',
41
 
                                  );
42
 
 
43
 
    /**
44
 
     * Returns an array of tokens this test wants to listen for.
45
 
     *
46
 
     * @return array
47
 
     */
48
 
    public function register()
49
 
    {
50
 
        return array(
51
 
                T_COMMENT,
52
 
                T_DOC_COMMENT,
53
 
               );
54
 
 
55
 
    }//end register()
56
 
 
57
 
 
58
 
    /**
59
 
     * Processes this test, when one of its tokens is encountered.
60
 
     *
61
 
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
62
 
     * @param int                  $stackPtr  The position of the current token in the
63
 
     *                                        stack passed in $tokens.
64
 
     *
65
 
     * @return void
66
 
     */
67
 
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
68
 
    {
69
 
        $tokens = $phpcsFile->getTokens();
70
 
 
71
 
        // If this is a function/class/interface doc block comment, skip it.
72
 
        // We are only interested in inline doc block comments, which are
73
 
        // not allowed.
74
 
        if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT) {
75
 
            $nextToken = $phpcsFile->findNext(
76
 
                PHP_CodeSniffer_Tokens::$emptyTokens,
77
 
                ($stackPtr + 1),
78
 
                null,
79
 
                true
80
 
            );
81
 
 
82
 
            $ignore = array(
83
 
                       T_CLASS,
84
 
                       T_INTERFACE,
85
 
                       T_TRAIT,
86
 
                       T_FUNCTION,
87
 
                       T_PUBLIC,
88
 
                       T_PRIVATE,
89
 
                       T_PROTECTED,
90
 
                       T_FINAL,
91
 
                       T_STATIC,
92
 
                       T_ABSTRACT,
93
 
                       T_CONST,
94
 
                       T_OBJECT,
95
 
                       T_PROPERTY,
96
 
                      );
97
 
 
98
 
            if (in_array($tokens[$nextToken]['code'], $ignore) === true) {
99
 
                return;
100
 
            } else {
101
 
                if ($phpcsFile->tokenizerType === 'JS') {
102
 
                    // We allow block comments if a function is being assigned
103
 
                    // to a variable.
104
 
                    $ignore    = PHP_CodeSniffer_Tokens::$emptyTokens;
105
 
                    $ignore[]  = T_EQUAL;
106
 
                    $ignore[]  = T_STRING;
107
 
                    $ignore[]  = T_OBJECT_OPERATOR;
108
 
                    $nextToken = $phpcsFile->findNext($ignore, ($nextToken + 1), null, true);
109
 
                    if ($tokens[$nextToken]['code'] === T_FUNCTION) {
110
 
                        return;
111
 
                    }
112
 
                }
113
 
 
114
 
                $prevToken = $phpcsFile->findPrevious(
115
 
                    PHP_CodeSniffer_Tokens::$emptyTokens,
116
 
                    ($stackPtr - 1),
117
 
                    null,
118
 
                    true
119
 
                );
120
 
 
121
 
                if ($tokens[$prevToken]['code'] === T_OPEN_TAG) {
122
 
                    return;
123
 
                }
124
 
 
125
 
                // Only error once per comment.
126
 
                if (substr($tokens[$stackPtr]['content'], 0, 3) === '/**') {
127
 
                    $error = 'Inline doc block comments are not allowed; use "/* Comment */" or "// Comment" instead';
128
 
                    $phpcsFile->addError($error, $stackPtr, 'DocBlock');
129
 
                }
130
 
            }//end if
131
 
        }//end if
132
 
 
133
 
        if ($tokens[$stackPtr]['content']{0} === '#') {
134
 
            $error = 'Perl-style comments are not allowed; use "// Comment" instead';
135
 
            $phpcsFile->addError($error, $stackPtr, 'WrongStyle');
136
 
        }
137
 
 
138
 
        // We don't want end of block comments. If the last comment is a closing
139
 
        // curly brace.
140
 
        $previousContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
141
 
        if ($tokens[$previousContent]['line'] === $tokens[$stackPtr]['line']) {
142
 
            if ($tokens[$previousContent]['code'] === T_CLOSE_CURLY_BRACKET) {
143
 
                return;
144
 
            }
145
 
 
146
 
            // Special case for JS files.
147
 
            if ($tokens[$previousContent]['code'] === T_COMMA
148
 
                || $tokens[$previousContent]['code'] === T_SEMICOLON
149
 
            ) {
150
 
                $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($previousContent - 1), null, true);
151
 
                if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) {
152
 
                    return;
153
 
                }
154
 
            }
155
 
        }
156
 
 
157
 
        $comment = rtrim($tokens[$stackPtr]['content']);
158
 
 
159
 
        // Only want inline comments.
160
 
        if (substr($comment, 0, 2) !== '//') {
161
 
            return;
162
 
        }
163
 
 
164
 
        $spaceCount = 0;
165
 
        for ($i = 2; $i < strlen($comment); $i++) {
166
 
            if ($comment[$i] !== ' ') {
167
 
                break;
168
 
            }
169
 
 
170
 
            $spaceCount++;
171
 
        }
172
 
 
173
 
        if ($spaceCount === 0) {
174
 
            $error = 'No space before comment text; expected "// %s" but found "%s"';
175
 
            $data  = array(
176
 
                      substr($comment, 2),
177
 
                      $comment,
178
 
                     );
179
 
            $phpcsFile->addError($error, $stackPtr, 'NoSpaceBefore', $data);
180
 
        }
181
 
 
182
 
        if ($spaceCount > 1) {
183
 
            $error = '%s spaces found before inline comment line; use block comment if you need indentation';
184
 
            $data  = array(
185
 
                      $spaceCount,
186
 
                      substr($comment, (2 + $spaceCount)),
187
 
                      $comment,
188
 
                     );
189
 
            $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data);
190
 
        }
191
 
 
192
 
 
193
 
        // The below section determines if a comment block is correctly capitalised,
194
 
        // and ends in a full-stop. It will find the last comment in a block, and
195
 
        // work its way up.
196
 
        $nextComment = $phpcsFile->findNext(array(T_COMMENT), ($stackPtr + 1), null, false);
197
 
 
198
 
        if (($nextComment !== false) && (($tokens[$nextComment]['line']) === ($tokens[$stackPtr]['line'] + 1))) {
199
 
            return;
200
 
        }
201
 
 
202
 
        $topComment  = $stackPtr;
203
 
        $lastComment = $stackPtr;
204
 
        while (($topComment = $phpcsFile->findPrevious(array(T_COMMENT), ($lastComment - 1), null, false)) !== false) {
205
 
            if ($tokens[$topComment]['line'] !== ($tokens[$lastComment]['line'] - 1)) {
206
 
                break;
207
 
            }
208
 
 
209
 
            $lastComment = $topComment;
210
 
        }
211
 
 
212
 
        $topComment  = $lastComment;
213
 
        $commentText = '';
214
 
 
215
 
        for ($i = $topComment; $i <= $stackPtr; $i++) {
216
 
            if ($tokens[$i]['code'] === T_COMMENT) {
217
 
                $commentText .= trim(substr($tokens[$i]['content'], 2));
218
 
            }
219
 
        }
220
 
 
221
 
        if ($commentText === '') {
222
 
            $error = 'Blank comments are not allowed';
223
 
            $phpcsFile->addError($error, $stackPtr, 'Empty');
224
 
            return;
225
 
        }
226
 
 
227
 
        if (preg_match('|\p{Lu}|u', $commentText[0]) === 0) {
228
 
            $error = 'Inline comments must start with a capital letter';
229
 
            $phpcsFile->addError($error, $topComment, 'NotCapital');
230
 
        }
231
 
 
232
 
        $commentCloser   = $commentText[(strlen($commentText) - 1)];
233
 
        $acceptedClosers = array(
234
 
                            'full-stops'        => '.',
235
 
                            'exclamation marks' => '!',
236
 
                            'or question marks' => '?',
237
 
                           );
238
 
 
239
 
        if (in_array($commentCloser, $acceptedClosers) === false) {
240
 
            $error = 'Inline comments must end in %s';
241
 
            $ender = '';
242
 
            foreach ($acceptedClosers as $closerName => $symbol) {
243
 
                $ender .= ' '.$closerName.',';
244
 
            }
245
 
 
246
 
            $ender = rtrim($ender, ',');
247
 
            $data  = array($ender);
248
 
            $phpcsFile->addError($error, $stackPtr, 'InvalidEndChar', $data);
249
 
        }
250
 
 
251
 
        // Finally, the line below the last comment cannot be empty if this inline
252
 
        // comment is on a line by itself.
253
 
        if ($tokens[$previousContent]['line'] < $tokens[$stackPtr]['line']) {
254
 
            $start = false;
255
 
            for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
256
 
                if ($tokens[$i]['line'] === ($tokens[$stackPtr]['line'] + 1)) {
257
 
                    if ($tokens[$i]['code'] !== T_WHITESPACE) {
258
 
                        return;
259
 
                    }
260
 
                } else if ($tokens[$i]['line'] > ($tokens[$stackPtr]['line'] + 1)) {
261
 
                    break;
262
 
                }
263
 
            }
264
 
 
265
 
            $error = 'There must be no blank line following an inline comment';
266
 
            $phpcsFile->addError($error, $stackPtr, 'SpacingAfter');
267
 
        }
268
 
 
269
 
    }//end process()
270
 
 
271
 
 
272
 
}//end class