Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * Squiz_Sniffs_Commenting_BlockCommentSniff.
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 Squiz Pty Ltd (ABN 77 084 670 600)
12
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
 * @version   CVS: $Id: BlockCommentSniff.php 253795 2008-02-26 04:03:14Z squiz $
14
 * @link      http://pear.php.net/package/PHP_CodeSniffer
15
 */
16
 
17
/**
18
 * Squiz_Sniffs_Commenting_BlockCommentSniff.
19
 *
20
 * Verifies that block comments are used appropriately.
21
 *
22
 * @category  PHP
23
 * @package   PHP_CodeSniffer
24
 * @author    Greg Sherwood <gsherwood@squiz.net>
25
 * @author    Marc McIntyre <mmcintyre@squiz.net>
26
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
27
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
28
 * @version   Release: 1.2.1
29
 * @link      http://pear.php.net/package/PHP_CodeSniffer
30
 */
31
class Squiz_Sniffs_Commenting_BlockCommentSniff implements PHP_CodeSniffer_Sniff
32
{
33
 
34
 
35
    /**
36
     * Returns an array of tokens this test wants to listen for.
37
     *
38
     * @return array
39
     */
40
    public function register()
41
    {
42
        return array(
43
                T_COMMENT,
44
                T_DOC_COMMENT,
45
               );
46
 
47
    }//end register()
48
 
49
 
50
    /**
51
     * Processes this test, when one of its tokens is encountered.
52
     *
53
     * @param PHP_CodeSniffer_File $phpcsFile The current file being scanned.
54
     * @param int                  $stackPtr  The position of the current token in the
55
     *                                        stack passed in $tokens.
56
     *
57
     * @return void
58
     */
59
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
60
    {
61
        $tokens = $phpcsFile->getTokens();
62
 
63
        // If its an inline comment return.
64
        if (substr($tokens[$stackPtr]['content'], 0, 2) !== '/*') {
65
            return;
66
        }
67
 
68
        // If this is a function/class/interface doc block comment, skip it.
69
        // We are only interested in inline doc block comments.
70
        if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT) {
71
            $nextToken = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
72
            $ignore    = array(
73
                          T_CLASS,
74
                          T_INTERFACE,
75
                          T_FUNCTION,
76
                          T_PUBLIC,
77
                          T_PRIVATE,
78
                          T_PROTECTED,
79
                          T_STATIC,
80
                          T_ABSTRACT,
81
                          T_CONST,
82
                         );
83
            if (in_array($tokens[$nextToken]['code'], $ignore) === true) {
84
                return;
85
            }
86
 
87
            $prevToken = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
88
            if ($tokens[$prevToken]['code'] === T_OPEN_TAG) {
89
                return;
90
            }
91
        }//end if
92
 
93
        $commentLines = array($stackPtr);
94
        $nextComment  = $stackPtr;
95
        $lastLine     = $tokens[$stackPtr]['line'];
96
 
97
        // Construct the comment into an array.
98
        while (($nextComment = $phpcsFile->findNext($tokens[$stackPtr]['code'], ($nextComment + 1), null, false)) !== false) {
99
            if (($tokens[$nextComment]['line'] - 1) !== $lastLine) {
100
                // Not part of the block.
101
                break;
102
            }
103
 
104
            $lastLine       = $tokens[$nextComment]['line'];
105
            $commentLines[] = $nextComment;
106
        }
107
 
108
        if (count($commentLines) <= 2) {
109
            // Small comment. Can't be right.
110
            if (count($commentLines) === 1) {
111
                $error = 'Single line block comment not allowed; use inline ("// text") comment instead';
112
                $phpcsFile->addError($error, $stackPtr);
113
                return;
114
            }
115
 
116
            if (trim($tokens[$commentLines[1]]['content']) === '*/') {
117
                if (trim($tokens[$stackPtr]['content']) === '/*') {
118
                    $error = 'Empty block comment not allowed';
119
                    $phpcsFile->addError($error, $stackPtr);
120
                    return;
121
                }
122
            }
123
        }
124
 
125
        $content = trim($tokens[$stackPtr]['content']);
126
        if ($content !== '/*' && $content !== '/**') {
127
            $error = 'Block comment text must start on a new line';
128
            $phpcsFile->addError($error, $stackPtr);
129
            return;
130
        }
131
 
132
        $starColumn = ($tokens[$stackPtr]['column'] + 3);
133
 
134
        // Make sure first line isn't blank.
135
        if (trim($tokens[$commentLines[1]]['content']) === '') {
136
            $error = 'Empty line not allowed at start of comment';
137
            $phpcsFile->addError($error, $commentLines[1]);
138
        } else {
139
            // Check indentation of first line.
140
            $content      = $tokens[$commentLines[1]]['content'];
141
            $commentText  = ltrim($content);
142
            $leadingSpace = (strlen($content) - strlen($commentText));
143
            if ($leadingSpace !== $starColumn) {
144
                $expected  = $starColumn;
145
                $expected .= ($starColumn === 1) ? ' space' : ' spaces';
146
                $error     = "First line of comment not aligned correctly; expected $expected but found $leadingSpace";
147
                $phpcsFile->addError($error, $commentLines[1]);
148
            }
149
 
150
            if (preg_match('|[A-Z]|', $commentText[0]) === 0) {
151
                $error = 'Block comments must start with a capital letter';
152
                $phpcsFile->addError($error, $commentLines[1]);
153
            }
154
        }
155
 
156
        // Check that each line of the comment is indented past the star.
157
        foreach ($commentLines as $line) {
158
            $leadingSpace = (strlen($tokens[$line]['content']) - strlen(ltrim($tokens[$line]['content'])));
159
            // First and last lines (comment opener and closer) are handled seperately.
160
            if ($line === $commentLines[(count($commentLines) - 1)] || $line === $commentLines[0]) {
161
                continue;
162
            }
163
 
164
            // First comment line was handled above.
165
            if ($line === $commentLines[1]) {
166
                continue;
167
            }
168
 
169
            // If it's empty, continue.
170
            if (trim($tokens[$line]['content']) === '') {
171
                continue;
172
            }
173
 
174
            if ($leadingSpace < $starColumn) {
175
                $expected  = $starColumn;
176
                $expected .= ($starColumn === 1) ? ' space' : ' spaces';
177
                $error     = "Comment line indented incorrectly; expected at least $expected but found $leadingSpace";
178
                $phpcsFile->addError($error, $line);
179
            }
180
        }//end foreach
181
 
182
        // Finally, test the last line is correct.
183
        $lastIndex = (count($commentLines) - 1);
184
        $content   = trim($tokens[$commentLines[$lastIndex]]['content']);
185
        if ($content !== '*/' && $content !== '**/') {
186
            $error = 'Comment closer must be on a new line';
187
            $phpcsFile->addError($error, $commentLines[$lastIndex]);
188
        } else {
189
            $content      = $tokens[$commentLines[$lastIndex]]['content'];
190
            $commentText  = ltrim($content);
191
            $leadingSpace = (strlen($content) - strlen($commentText));
192
            if ($leadingSpace !== ($tokens[$stackPtr]['column'] - 1)) {
193
                $expected  = ($tokens[$stackPtr]['column'] - 1);
194
                $expected .= ($expected === 1) ? ' space' : ' spaces';
195
                $error     = "Last line of comment aligned incorrectly; expected $expected but found $leadingSpace";
196
                $phpcsFile->addError($error, $commentLines[$lastIndex]);
197
            }
198
 
199
        }
200
 
201
        // Check that the lines before and after this comment are blank.
202
        $contentBefore = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
203
        if ($tokens[$contentBefore]['code'] === T_OPEN_CURLY_BRACKET) {
204
            if (($tokens[$stackPtr]['line'] - $tokens[$contentBefore]['line']) < 1) {
205
                $error = 'Empty line not required before block comment';
206
                $phpcsFile->addError($error, $stackPtr);
207
            }
208
        } else {
209
            if (($tokens[$stackPtr]['line'] - $tokens[$contentBefore]['line']) < 2) {
210
                $error = 'Empty line required before block comment';
211
                $phpcsFile->addError($error, $stackPtr);
212
            }
213
        }
214
 
215
        $commentCloser = $commentLines[$lastIndex];
216
        $contentAfter  = $phpcsFile->findNext(T_WHITESPACE, ($commentCloser + 1), null, true);
217
        if (($tokens[$contentAfter]['line'] - $tokens[$commentCloser]['line']) < 2) {
218
            $error = 'Empty line required after block comment';
219
            $phpcsFile->addError($error, $commentCloser);
220
        }
221
 
222
    }//end process()
223
 
224
 
225
}//end class
226
 
227
 
228
?>