Passed
Pull Request — master (#13)
by
unknown
01:53
created

MethodDocSniff::process()   F

Complexity

Conditions 31
Paths 5189

Size

Total Lines 135
Code Lines 81

Duplication

Lines 58
Ratio 42.96 %

Code Coverage

Tests 49
CRAP Score 93.6177

Importance

Changes 0
Metric Value
dl 58
loc 135
ccs 49
cts 82
cp 0.5976
rs 2
c 0
b 0
f 0
cc 31
eloc 81
nc 5189
nop 2
crap 93.6177

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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