Passed
Pull Request — master (#13)
by
unknown
05:33
created

MethodDocSniff   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 220
Duplicated Lines 26.36 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 60.71%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 30
c 1
b 0
f 0
lcom 0
cbo 2
dl 58
loc 220
ccs 51
cts 84
cp 0.6071
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 4 1
F process() 58 139 29

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace BestIt\Sniffs\Commenting;
4
5
use PHP_CodeSniffer_File;
6
use PHP_CodeSniffer_Sniff;
7
8
/**
9
 * This Sniff checks the method phpdoc
10
 *
11
 * It is a modified version of the Generic DocCommentSniff adjusted for the bestit codestyle
12
 *
13
 * @package BestIt\Sniffs\Commenting
14
 */
15
class MethodDocSniff implements PHP_CodeSniffer_Sniff
16
{
17
    /**
18
     * Code for an empty doc block
19
     *
20
     * @var string
21
     */
22
    const CODE_EMPTY = 'Empty';
23
24
    /**
25
     * Code for missing spacing between descriptions
26
     *
27
     * @var string
28
     */
29
    const CODE_SPACING_BETWEEN = 'SpacingBetween';
30
31
    /**
32
     * Code for missing spacing before the tags
33
     *
34
     * @var string
35
     */
36
    const CODE_SPACING_BEFORE_TAGS = 'SpacingBeforeTags';
37
38
    /**
39
     * Code for missing short description (Summary)
40
     *
41
     * @var string
42
     */
43
    const CODE_MISSING_SHORT = 'MissingShort';
44
45
    /**
46
     * Code for not capitalized short description
47
     *
48
     * @var string
49
     */
50
    const CODE_SHORT_NOT_CAPITAL = 'ShortNotCapital';
51
52
    /**
53
     * Code for not Capitalized long description
54
     *
55
     * @var string
56
     */
57
    const CODE_LONG_NOT_CAPITAL = 'LongNotCapital';
58
59
    /**
60
     * Code for empty lines before the short description
61
     *
62
     * @var string
63
     */
64
    const CODE_SPACING_BEFORE_SHORT = 'SpacingBeforeShort';
65
66
    /**
67
     * A list of tokenizers this sniff supports.
68
     *
69
     * @var array
70
     */
71
    public $supportedTokenizers = [
72
        'PHP',
73
        'JS',
74
    ];
75
76
77
    /**
78
     * Returns an array of tokens this test wants to listen for.
79
     *
80
     * @return array
81
     */
82 6
    public function register()
83
    {
84 6
        return array(T_DOC_COMMENT_OPEN_TAG);
85
    }
86
87
    /**
88
     * Processes this test, when one of its tokens is encountered.
89
     *
90
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
91
     * @param int $stackPtr  The position of the current token in the stack passed in $tokens.
92
     *
93
     * @return void
94
     */
95 6
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
96
    {
97 6
        $tokens       = $phpcsFile->getTokens();
98 6
        $commentStart = $stackPtr;
99 6
        $commentEnd   = $tokens[$stackPtr]['comment_closer'];
100
101
        $empty = array(
102 6
            T_DOC_COMMENT_WHITESPACE,
103 6
            T_DOC_COMMENT_STAR,
104
        );
105
106 6
        $short = $phpcsFile->findNext($empty, $stackPtr + 1, $commentEnd, true);
107 6
        if ($short === false) {
108
            // No content at all.
109 1
            $error = 'Doc comment is empty';
110 1
            $phpcsFile->addError($error, $stackPtr, self::CODE_EMPTY);
111 1
            return;
112
        }
113
114
        // The last line of the comment should just be the */ code.
115 5
        $prev = $phpcsFile->findPrevious($empty, $commentEnd - 1, $stackPtr, true);
116
117
        // Check for additional blank lines at the end of the comment.
118 5
        if ($tokens[$prev]['line'] < ($tokens[$commentEnd]['line'] - 1)) {
119
            $error = 'Additional blank lines found at end of doc comment';
120
            $fix   = $phpcsFile->addFixableError($error, $commentEnd, 'SpacingAfter');
121
            if ($fix === true) {
122
                $phpcsFile->fixer->beginChangeset();
123 View Code Duplication
                for ($i = ($prev + 1); $i < $commentEnd; $i++) {
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...
124
                    if ($tokens[$i + 1]['line'] === $tokens[$commentEnd]['line']) {
125
                        break;
126
                    }
127
128
                    $phpcsFile->fixer->replaceToken($i, '');
129
                }
130
131
                $phpcsFile->fixer->endChangeset();
132
            }
133
        }
134
135
        // Check for a comment description.
136 5
        if ($tokens[$short]['code'] !== T_DOC_COMMENT_STRING) {
137 1
            $error = 'Missing short description in doc comment';
138 1
            $phpcsFile->addError($error, $stackPtr, self::CODE_MISSING_SHORT);
139 1
            return;
140
        }
141
142
        // No extra newline before short description.
143 4 View Code Duplication
        if ($tokens[$short]['line'] !== ($tokens[$stackPtr]['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...
144 1
            $error = 'Doc comment short description must be on the first line';
145 1
            $fix   = $phpcsFile->addFixableError($error, $short, self::CODE_SPACING_BEFORE_SHORT);
146 1
            if ($fix === true) {
147
                $phpcsFile->fixer->beginChangeset();
148
                for ($i = $stackPtr; $i < $short; $i++) {
149
                    if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) {
150
                        continue;
151
                    } elseif ($tokens[$i]['line'] === $tokens[$short]['line']) {
152
                        break;
153
                    }
154
155
                    $phpcsFile->fixer->replaceToken($i, '');
156
                }
157
158
                $phpcsFile->fixer->endChangeset();
159
            }
160
        }
161
162
        // Account for the fact that a short description might cover
163
        // multiple lines.
164 4
        $shortContent = $tokens[$short]['content'];
165 4
        $shortEnd     = $short;
166
167
168 4
        if (preg_match('/^\p{Ll}/u', $shortContent) === 1) {
169 1
            $error = 'Doc comment short description must start with a capital letter';
170 1
            $phpcsFile->addError($error, $short, self::CODE_SHORT_NOT_CAPITAL);
171
        }
172
173 4
        $long = $phpcsFile->findNext($empty, $shortEnd + 1, $commentEnd - 1, true);
174 4
        if ($long !== false && $tokens[$long]['code'] === T_DOC_COMMENT_STRING) {
175 2 View Code Duplication
            if (preg_match('/^\p{Ll}/u', $tokens[$long]['content']) === 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...
176 1
                $error = 'Doc comment long description must start with a capital letter';
177 1
                $phpcsFile->addError($error, $long, self::CODE_LONG_NOT_CAPITAL);
178
            }
179
        }
180
181 4
        $long = $phpcsFile->findNext($empty, $shortEnd + 1, $commentEnd - 1, true);
182 4
        if ($long !== false && $tokens[$long]['code'] === T_DOC_COMMENT_STRING) {
183 2 View Code Duplication
            if ($tokens[$long]['line'] !== ($tokens[$shortEnd]['line'] + 2)) {
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...
184 1
                $error = 'There must be exactly one blank line between descriptions in a doc comment';
185 1
                $fix   = $phpcsFile->addFixableError($error, $long, self::CODE_SPACING_BETWEEN);
186 1
                if ($fix === true) {
187
                    $phpcsFile->fixer->beginChangeset();
188
                    for ($i = ($shortEnd + 1); $i < $long; $i++) {
189
                        if ($tokens[$i]['line'] === $tokens[$shortEnd]['line']) {
190
                            continue;
191
                        } elseif ($tokens[$i]['line'] === ($tokens[$long]['line'] - 1)) {
192
                            break;
193
                        }
194
195
                        $phpcsFile->fixer->replaceToken($i, '');
196
                    }
197
198
                    $phpcsFile->fixer->endChangeset();
199
                }
200
            }
201
202 2 View Code Duplication
            if (preg_match('/^\p{Ll}/u', $tokens[$long]['content']) === 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...
203 1
                $error = 'Doc comment long description must start with a capital letter';
204 1
                $phpcsFile->addError($error, $long, self::CODE_LONG_NOT_CAPITAL);
205
            }
206
        }
207
208 4
        if (empty($tokens[$commentStart]['comment_tags']) === true) {
209
            // No tags in the comment.
210 1
            return;
211
        }
212
213 4
        $firstTag = $tokens[$commentStart]['comment_tags'][0];
214 4
        $prev     = $phpcsFile->findPrevious($empty, $firstTag - 1, $stackPtr, true);
215 4
        if ($tokens[$firstTag]['line'] !== ($tokens[$prev]['line'] + 2)) {
216 1
            $error = 'There must be exactly one blank line before the tags in a doc comment';
217 1
            $fix   = $phpcsFile->addFixableError($error, $firstTag, self::CODE_SPACING_BEFORE_TAGS);
218 1
            if ($fix === true) {
219
                $phpcsFile->fixer->beginChangeset();
220 View Code Duplication
                for ($i = ($prev + 1); $i < $firstTag; $i++) {
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...
221
                    if ($tokens[$i]['line'] === $tokens[$firstTag]['line']) {
222
                        break;
223
                    }
224
225
                    $phpcsFile->fixer->replaceToken($i, '');
226
                }
227
228
                $indent = str_repeat(' ', $tokens[$stackPtr]['column']);
229
                $phpcsFile->fixer->addContent($prev, $phpcsFile->eolChar.$indent.'*'.$phpcsFile->eolChar);
230
                $phpcsFile->fixer->endChangeset();
231
            }
232
        }
233 4
    }
234
}
235