Completed
Push — master ( a32632...c637b7 )
by Juliette
9s
created

NewLanguageConstructsSniff::addError()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
cc 6
eloc 14
nc 12
nop 3

1 Method

Rating   Name   Duplication   Size   Complexity  
A NewLanguageConstructsSniff::getNonVersionArrayKeys() 0 4 1
1
<?php
2
/**
3
 * PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff.
4
 *
5
 * PHP version 5.5
6
 *
7
 * @category  PHP
8
 * @package   PHPCompatibility
9
 * @author    Wim Godden <[email protected]>
10
 * @copyright 2013 Cu.be Solutions bvba
11
 */
12
13
/**
14
 * PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff.
15
 *
16
 * @category  PHP
17
 * @package   PHPCompatibility
18
 * @author    Wim Godden <[email protected]>
19
 * @version   1.0.0
20
 * @copyright 2013 Cu.be Solutions bvba
21
 */
22
class PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff extends PHPCompatibility_AbstractNewFeatureSniff
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
23
{
24
25
    /**
26
     * A list of new language constructs, not present in older versions.
27
     *
28
     * The array lists : version number with false (not present) or true (present).
29
     * If's sufficient to list the first version where the keyword appears.
30
     *
31
     * @var array(string => array(string => int|string|null))
32
     */
33
    protected $newConstructs = array(
34
                                        'T_NS_SEPARATOR' => array(
35
                                            '5.2' => false,
36
                                            '5.3' => true,
37
                                            'description' => 'the \ operator (for namespaces)'
38
                                        ),
39
                                        'T_POW' => array(
40
                                            '5.5' => false,
41
                                            '5.6' => true,
42
                                            'description' => 'power operator (**)'
43
                                        ), // identified in PHPCS 1.5 as T_MULTIPLY + T_MULTIPLY
44
                                        'T_POW_EQUAL' => array(
45
                                            '5.5' => false,
46
                                            '5.6' => true,
47
                                            'description' => 'power assignment operator (**=)'
48
                                        ), // identified in PHPCS 1.5 as T_MULTIPLY + T_MUL_EQUAL
49
                                        'T_ELLIPSIS' => array(
50
                                            '5.5' => false,
51
                                            '5.6' => true,
52
                                            'description' => 'variadic functions using ...'
53
                                        ),
54
                                        'T_SPACESHIP' => array(
55
                                            '5.6' => false,
56
                                            '7.0' => true,
57
                                            'description' => 'spaceship operator (<=>)'
58
                                        ), // identified in PHPCS 1.5 as T_IS_SMALLER_OR_EQUAL + T_GREATER_THAN
59
                                        'T_COALESCE' => array(
60
                                            '5.6' => false,
61
                                            '7.0' => true,
62
                                            'description' => 'null coalescing operator (??)'
63
                                        ), // identified in PHPCS 1.5 as T_INLINE_THEN + T_INLINE_THEN
64
                                    );
65
66
67
    /**
68
     * A list of new language constructs which are not recognized in PHPCS 1.x.
69
     *
70
     * The array lists an alternative token to listen for.
71
     *
72
     * @var array(string => int)
73
     */
74
    protected $newConstructsPHPCSCompat = array(
75
                                        'T_POW'       => T_MULTIPLY,
76
                                        'T_POW_EQUAL' => T_MUL_EQUAL,
77
                                        'T_SPACESHIP' => T_GREATER_THAN,
78
                                        'T_COALESCE'  => T_INLINE_THEN,
79
                                    );
80
81
    /**
82
     * Translation table for PHPCS 1.x tokens.
83
     *
84
     * The 'before' index lists the token which would have to be directly before the
85
     * token found for it to be one of the new language constructs.
86
     * The 'real_token' index indicates which language construct was found in that case.
87
     *
88
     * {@internal 'before' was choosen rather than 'after' as that allowed for a 1-on-1
89
     * translation list with the current tokens.}}
90
     *
91
     * @var array(string => array(string => string))
92
     */
93
    protected $PHPCSCompatTranslate = array(
94
                                        'T_MULTIPLY' => array(
95
                                            'before' => 'T_MULTIPLY',
96
                                            'real_token' => 'T_POW',
97
                                        ),
98
                                        'T_MUL_EQUAL' => array(
99
                                            'before' => 'T_MULTIPLY',
100
                                            'real_token' => 'T_POW_EQUAL',
101
                                        ),
102
                                        'T_GREATER_THAN' => array(
103
                                            'before' => 'T_IS_SMALLER_OR_EQUAL',
104
                                            'real_token' => 'T_SPACESHIP',
105
                                        ),
106
                                        'T_INLINE_THEN' => array(
107
                                            'before' => 'T_INLINE_THEN',
108
                                            'real_token' => 'T_COALESCE',
109
                                        ),
110
                                    );
111
112
    /**
113
     * Returns an array of tokens this test wants to listen for.
114
     *
115
     * @return array
116
     */
117
    public function register()
118
    {
119
        $tokens = array();
120
        foreach ($this->newConstructs as $token => $versions) {
121
            if (defined($token)) {
122
                $tokens[] = constant($token);
123
            }
124
            else if(isset($this->newConstructsPHPCSCompat[$token])) {
125
                $tokens[] = $this->newConstructsPHPCSCompat[$token];
126
            }
127
        }
128
        return $tokens;
129
    }//end register()
130
131
132
    /**
133
     * Processes this test, when one of its tokens is encountered.
134
     *
135
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
136
     * @param int                  $stackPtr  The position of the current token in
137
     *                                        the stack passed in $tokens.
138
     *
139
     * @return void
140
     */
141
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
142
    {
143
        $tokens    = $phpcsFile->getTokens();
144
        $tokenType = $tokens[$stackPtr]['type'];
145
146
        // Translate pre-PHPCS 2.0 tokens for new constructs to the actual construct.
147
        if (isset($this->newConstructs[$tokenType]) === false) {
148
            if (
149
                isset($this->PHPCSCompatTranslate[$tokenType])
150
                &&
151
                $tokens[$stackPtr - 1]['type'] === $this->PHPCSCompatTranslate[$tokenType]['before']
152
            ) {
153
                $tokenType = $this->PHPCSCompatTranslate[$tokenType]['real_token'];
154
            }
155
        }
156
157
        // If the translation did not yield one of the tokens we are looking for, bow out.
158
        if (isset($this->newConstructs[$tokenType]) === false) {
159
            return;
160
        }
161
162
        $itemInfo = array(
163
            'name'   => $tokenType,
164
        );
165
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
166
167
    }//end process()
168
169
170
    /**
171
     * Get the relevant sub-array for a specific item from a multi-dimensional array.
172
     *
173
     * @param array $itemInfo Base information about the item.
174
     *
175
     * @return array Version and other information about the item.
176
     */
177
    public function getItemArray(array $itemInfo)
178
    {
179
        return $this->newConstructs[$itemInfo['name']];
180
    }
181
182
183
    /**
184
     * Get an array of the non-PHP-version array keys used in a sub-array.
185
     *
186
     * @return array
187
     */
188
    protected function getNonVersionArrayKeys()
189
    {
190
        return array('description');
191
    }
192
193
194
    /**
195
     * Retrieve the relevant detail (version) information for use in an error message.
196
     *
197
     * @param array $itemArray Version and other information about the item.
198
     * @param array $itemInfo  Base information about the item.
199
     *
200
     * @return array
201
     */
202
    public function getErrorInfo(array $itemArray, array $itemInfo)
203
    {
204
        $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
205
        $errorInfo['description'] = $itemArray['description'];
206
207
        return $errorInfo;
208
209
    }
210
211
212
    /**
213
     * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
214
     *
215
     * @param array $data      The error data array which was created.
216
     * @param array $itemInfo  Base information about the item this error message applied to.
217
     * @param array $errorInfo Detail information about an item this error message applied to.
218
     *
219
     * @return array
220
     */
221
    protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
222
    {
223
        $data[0] = $errorInfo['description'];
224
        return $data;
225
    }
226
227
228
}//end class
229