Passed
Push — master ( 2927c7...98f658 )
by Michael
01:46
created

ArrayDoubleArrowAlignmentSniff::process()   D

Complexity

Conditions 16
Paths 80

Size

Total Lines 85
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 51
nc 80
nop 2
dl 0
loc 85
rs 4.8736
c 0
b 0
f 0

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
/**
4
 * This file is part of the mo4-coding-standard (phpcs standard)
5
 *
6
 * PHP version 5
7
 *
8
 * @category PHP
9
 * @package  PHP_CodeSniffer-MO4
10
 * @author   Xaver Loppenstedt <[email protected]>
11
 * @license  http://spdx.org/licenses/MIT MIT License
12
 * @version  GIT: master
13
 * @link     https://github.com/Mayflower/mo4-coding-standard
14
 */
15
namespace MO4\Sniffs\Arrays;
16
17
use PHP_CodeSniffer\Files\File;
18
use PHP_CodeSniffer\Sniffs\Sniff;
19
use PHP_CodeSniffer\Util\Tokens as PHP_CodeSniffer_Tokens;
20
21
/**
22
 * Array Double Arrow Alignment sniff.
23
 *
24
 * '=>' must be aligned in arrays, and the key and the '=>' must be in the same line
25
 *
26
 * @category  PHP
27
 * @package   PHP_CodeSniffer-MO4
28
 * @author    Xaver Loppenstedt <[email protected]>
29
 * @copyright 2013 Xaver Loppenstedt, some rights reserved.
30
 * @license   http://spdx.org/licenses/MIT MIT License
31
 * @link      https://github.com/Mayflower/mo4-coding-standard
32
 */
33
class ArrayDoubleArrowAlignmentSniff implements Sniff
34
{
35
    /**
36
     * Define all types of arrays.
37
     *
38
     * @var array
39
     */
40
    protected  $arrayTokens = array(
41
                               T_ARRAY,
42
                               T_OPEN_SHORT_ARRAY,
43
                              );
44
45
46
    /**
47
     * Registers the tokens that this sniff wants to listen for.
48
     *
49
     * @return array(int)
50
     * @see    Tokens.php
51
     */
52
    public function register()
53
    {
54
        return $this->arrayTokens;
55
56
    }//end register()
57
58
59
    /**
60
     * Processes this test, when one of its tokens is encountered.
61
     *
62
     * @param File $phpcsFile The file being scanned.
63
     * @param int  $stackPtr  The position of the current token in
64
     *                        the stack passed in $tokens.
65
     *
66
     * @return void
67
     */
68
    public function process(File $phpcsFile, $stackPtr)
69
    {
70
        $tokens  = $phpcsFile->getTokens();
71
        $current = $tokens[$stackPtr];
72
73
        if ($current['code'] === T_ARRAY) {
74
            $start = $current['parenthesis_opener'];
75
            $end   = $current['parenthesis_closer'];
76
        } else {
77
            $start = $current['bracket_opener'];
78
            $end   = $current['bracket_closer'];
79
        }
80
81
        if ($tokens[$start]['line'] === $tokens[$end]['line']) {
82
            return;
83
        }
84
85
        $assignments  = array();
86
        $keyEndColumn = -1;
87
        $lastLine     = -1;
88
89
        for ($i = ($start + 1); $i < $end; $i++) {
90
            $current  = $tokens[$i];
91
            $previous = $tokens[($i - 1)];
92
93
            // Skip nested arrays.
94
            if ((in_array($current['code'], $this->arrayTokens)) === true) {
95
                if ($current['code'] === T_ARRAY) {
96
                    $i = ($current['parenthesis_closer'] + 1);
97
                } else {
98
                    $i = ($current['bracket_closer'] + 1);
99
                }
100
101
                continue;
102
            }
103
104
            // Skip closures in array.
105
            if ($current['code'] === T_CLOSURE) {
106
                $i = ($current['scope_closer'] + 1);
107
                continue;
108
            }
109
110
            if ($current['code'] === T_DOUBLE_ARROW) {
111
                $assignments[] = $i;
112
                $column        = $previous['column'];
113
                $line          = $current['line'];
114
115
                if ($lastLine === $line) {
116
                    $msg = 'only one "=>" assignments per line is allowed in a multi line array';
117
                    $phpcsFile->addError($msg, $i, 'OneAssignmentPerLine');
118
                }
119
120
                $hasKeyInLine = false;
121
122
                $j = ($i - 1);
123
                while (($j >= 0) && ($tokens[$j]['line'] === $current['line'])) {
124
                    if ((in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::$emptyTokens)) === false) {
125
                        $hasKeyInLine = true;
126
                    }
127
128
                    $j--;
129
                }
130
131
                if ($hasKeyInLine === false) {
132
                    $phpcsFile->addError(
133
                        'in arrays, keys and "=>" must be on the same line',
134
                        $i,
135
                        'KeyAndValueNotOnSameLine'
136
                    );
137
                }
138
139
                if ($column > $keyEndColumn) {
140
                    $keyEndColumn = $column;
141
                }
142
143
                $lastLine = $line;
144
            }//end if
145
        }//end for
146
147
        foreach ($assignments as $ptr) {
148
            $current = $tokens[$ptr];
149
            $column  = $current['column'];
150
151
            if ($column !== ($keyEndColumn + 1)) {
152
                $phpcsFile->addError('each "=>" assignments must be aligned', $ptr, 'AssignmentsNotAligned');
153
            }
154
        }
155
156
    }//end process()
157
158
159
}//end class
160